package com.testes.umov.view;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.testes.umov.R;
import com.testes.umov.enums.OperationType;
import com.testes.umov.model.TestData;
import com.testes.umov.sync.LogAdapter;
import com.testes.umov.sync.SyncTestsController;
import com.testes.umov.util.ControllerListener;

public class SyncTestActivity extends Activity implements ControllerListener {
	private List<Integer> list;
	private Button buttonAddField, buttonGo;
	private EditText textFieldSize, textMaxItems;
	private TextView textViewFieldCount, textViewCharCount;
	private SyncTestsController controller;
	private ListView listView;
	List<TestData> resultsList = new ArrayList<TestData>();
	private LogAdapter adapter;
	private int itemsPerSync = 200;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_sync_test);

		setControls();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_sync_test, menu);
		return true;
	}

	@SuppressLint("NewApi")
	@Override
	public void onBackPressed() {
		if (!buttonAddField.isEnabled()) {
			Toast toast = Toast.makeText(this,
					"Wait till the tests are finished.", Toast.LENGTH_LONG);
			toast.show();
		} else {
			super.onBackPressed();
		}
	}

	private void setControls() {
		list = new ArrayList<Integer>();
		textFieldSize = (EditText) findViewById(R.id.tests_sync_field_size_edit_text);
		textMaxItems = (EditText) findViewById(R.id.tests_sync_max_items);
		textViewFieldCount = (TextView) findViewById(R.id.tests_sync_field_count_label);
		textViewCharCount = (TextView) findViewById(R.id.tests_sync_char_count_label);
		buttonAddField = (Button) findViewById(R.id.tests_sync_field_buttonAdd);
		this.listView = (ListView) findViewById(R.id.syncListView);
		this.adapter = new LogAdapter(this, 0, 0, new ArrayList<TestData>());
		this.listView.setAdapter(this.adapter);

		buttonAddField.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				runOnUiThread(new Runnable() {
					public void run() {
						String value = textFieldSize.getText().toString();
						if (value == null || value == "" || value.length() <= 0) {
							showEmptyFieldSizeMessage();
						} else {
							Integer lenght = Integer.parseInt(value);
							list.add(lenght);
							// textFieldSize.setText("");
							calculateFieldCountAndCharCount();
						}
					}
				});

			}
		});

		buttonGo = (Button) findViewById(R.id.tests_sync_field_buttonGo);
		buttonGo.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				startTests();
			}
		});
	}

	private void showEmptyFieldSizeMessage() {
		Toast toast = Toast.makeText(this,
				"Please type in the max quantity of items that can be sent.",
				Toast.LENGTH_LONG);
		toast.show();
	}

	private void calculateFieldCountAndCharCount() {
		String fields = list.size() + " fields";
		textViewFieldCount.setText(fields);

		int charCount = 0;
		for (Integer i : this.list) {
			charCount += (int) i;
		}

		String chars = charCount + " chars";
		textViewCharCount.setText(chars);
	}

	private void startTests() {
		this.buttonAddField.setEnabled(false);
		this.buttonGo.setEnabled(false);

		String input = textMaxItems.getText().toString();
		if (input == null || input == "" || input.length() <= 0) {
			Toast toast = Toast
					.makeText(
							this,
							"Please type in the max quantity of items that can be sent.",
							Toast.LENGTH_LONG);
			toast.show();
		} else if (list.size() <= 0) {
			Toast toast = Toast.makeText(this,
					"Please insert one or more fields.", Toast.LENGTH_LONG);
			toast.show();
		} else {
			itemsPerSync = Integer.parseInt(input);
			Integer[] fieldSizes = list.toArray(new Integer[list.size()]);
			controller = new SyncTestsController(this, fieldSizes, itemsPerSync);
			controller.setListener(this);
			controller.doTests();
		}

	}

	@Override
	public void onTestsFinished(Hashtable<String, Object> results) {
		this.buttonAddField.setEnabled(true);
		this.buttonGo.setEnabled(true);
	}

	@Override
	synchronized public void onPartialTestFinished(TestData testData) {
		if (testData.getType() == OperationType.CPU) {
			String description = "\nParsing test results:\n\n";
			description += "\nTotal items parsed: " + testData.getOperations();
			description += "\nTotal time spend: " + testData.getSpentTime();
			description += "\nTotal battery spend: " + testData.getSpentCharge();
			description += "\nNumber of items: " + testData.getOperations();
			description += "\nAverage time per item: " + 
							(float) ((float) testData.getSpentTime() / (float) testData.getOperations());
			description += "\nAverage time per " + itemsPerSync	+ " items: " 
							+ (float) ((float) testData.getSpentTime() / (float) (testData.getOperations() / itemsPerSync));
			float averageBatterySpent = 2.0f / (float) testData.getOperations();
			description += "\nAverage battery spent per item: "	+ averageBatterySpent;
			description += "\nAverage battery spent per " + itemsPerSync + " items parsing: " 
							+ (float) (2.0f / (float) (testData.getOperations() / itemsPerSync));
			testData.setDescription(description);
			this.adapter.addData(testData);
		} else if (testData.getType() == OperationType.SYNC) {
			String description = "\nSync test results:\n\n";
			description += "\nTotal items sent: " + testData.getOperations();
			description += "\nTotal bytes sent: " + testData.getDataLenght();
			description += "\nTotal time spend: " + testData.getSpentTime();
			description += "\nTotal battery spend: " + testData.getSpentCharge();
			description += "\nNumber of syncs: " + (testData.getOperations() / itemsPerSync);
			description += "\nAverage time per item: " + (float) ((float) testData.getSpentTime() / (float) testData
							.getOperations());
			description += "\nAverage time per sync: " + (float) ((float) testData.getSpentTime() / (float) (testData
							.getOperations() / itemsPerSync));
			float averageBatterySpent = 2.0f / (float) testData.getOperations();
			description += "\nAverage battery spent per item: "	+ averageBatterySpent;
			description += "\nAverage battery spent per sync: "	+ (float) (2.0f / (float) ((float) testData.getOperations() / (float) itemsPerSync));
			testData.setDescription(description);
			this.adapter.addData(testData);
		}

	}

}
